/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package webOffline;

/**
 *
 * @author Do Viet Trung
 */
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.io.*;
import java.util.ArrayList;
import javax.xml.parsers.*;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
//import org.xml.sax.*;

public class DOMXml {
     private static String defaultStringXml = "<?xml version=" + '"' + "1.0" + '"'
            + " encoding=" + '"' + "UTF-8" + '"' + "?>\n";
   
     public static ArrayList<String> readFileTypes(String path) throws Exception {
         ArrayList<String> list = new ArrayList<String>();
         File file = new File(path);
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder db = dbf.newDocumentBuilder();
         Document doc = db.parse(file);
         doc.getDocumentElement().normalize();
         System.out.println("Root element " + doc.getDocumentElement().getNodeName());

         NodeList nodeLst = doc.getElementsByTagName("Ext");
         System.out.println("Information of all employees");
      
         for (int s = 0; s < nodeLst.getLength(); s++) {
             Node fstNode = nodeLst.item(s);
            
             if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
                 Element fstElmnt = (Element) fstNode;
                 list.add(fstElmnt.getAttribute("type"));
             }
         }

         return list;
     }

   
     public static void createFileTypes (ArrayList<String>arrTypes,
                                         String filepathDest) throws Exception
     {
         DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
         DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
         Document doc = docBuilder.newDocument();
         Element root = doc.createElement("FileTypes");
         doc.appendChild(root);
         Comment comment = doc.createComment("File Types");
         root.appendChild(comment);

         for(int i = 0; i < arrTypes.size(); i++) {
             Element child = doc.createElement("Ext");
             child.setAttribute("type", arrTypes.get(i ));
             child.setAttribute("des", "none");
             root.appendChild(child);
         }

         TransformerFactory transfac = TransformerFactory.newInstance();
         Transformer trans = transfac.newTransformer();
         trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
         trans.setOutputProperty(OutputKeys.INDENT, "yes");

         StringWriter sw = new StringWriter();
         StreamResult result = new StreamResult(sw);
         DOMSource source = new DOMSource(doc);
         trans.transform(source, result);

         String xmlString = sw.toString();
         xmlString = defaultStringXml + xmlString;

         //print xml
         System.out.println("Here's the xml:\n\n" + xmlString);

         PrintWriter pw = new PrintWriter(filepathDest);
         pw.write(xmlString);
         pw.close();
     }

    public static ProjectDownloadManager openProject (String path) throws Exception {
        //lntrung
        ProjectDownloadManager proManager = new ProjectDownloadManager();
        try{
            //Tạo ProjectDownloadManager
            ProjectAddress proAddress =  new ProjectAddress();
            File file = new File(path);
            if (file.exists() == false){
                System.out.println("Error : " + path + " ko tồn tại.");
                return proManager;
            }

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(file);

            //Lấy các thuộc tính của thẻ ProjectAddress
            Element eleProjectAddress = (Element)doc.getElementsByTagName("ProjectAddress").item(0);
            proAddress.setProjectName(eleProjectAddress.getAttribute("name"));
            proAddress.setAddress(eleProjectAddress.getAttribute("address"));
            proAddress.setUpLink(Integer.parseInt(eleProjectAddress.getAttribute("upLink")));
            proAddress.setSaveTo(eleProjectAddress.getAttribute("saveTo"));

            //Lấy các thuộc tính của tag Ext
            ArrayList<String> listExt = new ArrayList<String>();
            NodeList nodeList = eleProjectAddress.getElementsByTagName("Ext");
            for(int i = 0; i < nodeList.getLength(); i++){
                Element eleExt = (Element)nodeList.item(i);
                listExt.add(eleExt.getAttribute("name"));
            }
            proAddress.setListExt(listExt);

            //Lấy các thuộc tính của tag Pattern
            ArrayList<Pattern> listPattern = new ArrayList<Pattern>();
            nodeList = eleProjectAddress.getElementsByTagName("Pattern");
            for(int i = 0; i < nodeList.getLength(); i++){
                Element elePattern = (Element)nodeList.item(i);
                String permission = elePattern.getAttribute("permission");
                PermissionPattern permissionPattern;
//                ArrayList<Extension> listExtension = new ArrayList<Extension>();

                if(permission.toUpperCase().equals("ALLOW_ALL")){
                    permissionPattern = PermissionPattern.ALLOW_ALL;
                } else if (permission.toUpperCase().equals("ALLOW_ITEMS")){
                    permissionPattern = PermissionPattern.ALLOW_ITEMS;
                } else if (permission.toUpperCase().equals("DENY_ALL")){
                    permissionPattern = PermissionPattern.DENY_ALL;
                } else {
                    permissionPattern = PermissionPattern.DENY_ITEMS;
                }
                Pattern pattern = new Pattern(elePattern.getAttribute("name"), permissionPattern);
                if(pattern.getPermission().equals(PermissionPattern.ALLOW_ALL) == true || pattern.getPermission().equals(PermissionPattern.DENY_ALL) == true){
                    pattern.createExtension(listExt);
                } else {
                    String value = "";
                    if (pattern.getPermission().equals(PermissionPattern.ALLOW_ITEMS) == true){
                        value = ((Element)elePattern.getElementsByTagName("AllowExt").item(0)).getTextContent();
                        String []values = value.split(",");
                        int []listChoose = new int[values.length];
                        for(int j = 0; j < values.length; j++){
                            listChoose[j] = Integer.parseInt(values[j]);
                        }
                        pattern.createExtension(listExt, listChoose, PermissionExtension.ALLOW, PermissionExtension.DENY);
                    } else {
                        value = ((Element)elePattern.getElementsByTagName("DenyExt").item(0)).getTextContent();
                        String []values = value.split(",");
                        int []listChoose = new int[values.length];
                        for(int j = 0; j < values.length; j++){
                            listChoose[j] = Integer.parseInt(values[j]);
                        }
                        pattern.createExtension(listExt, listChoose, PermissionExtension.DENY, PermissionExtension.ALLOW);
                    }
                }

                listPattern.add(pattern);
            }
            proAddress.setArrayPattern(listPattern);

            //Tạo ProjectDownloadManager
            proManager = new ProjectDownloadManager(proAddress);

            //Lấy danh sách ProjectDownloadLinks
            ArrayList<ProjectDownloadLinks> listDownloadingLink = new ArrayList<ProjectDownloadLinks>();
            Element eleDownloading = (Element)doc.getElementsByTagName("Downloading").item(0);
            nodeList = eleDownloading.getElementsByTagName("Link");
            for(int i = 0; i < nodeList.getLength(); i++){
                Element eleDownloadingLink = (Element)nodeList.item(i);
                ProjectDownloadLinks downloadingLink = new ProjectDownloadLinks(eleDownloadingLink.getAttribute("url"));
                downloadingLink.setLevel(Integer.parseInt(eleDownloadingLink.getAttribute("level")));
                downloadingLink.setSaveTo(eleDownloadingLink.getAttribute("saveTo"));

                listDownloadingLink.add(downloadingLink);
            }
            proManager.getStartingAddress().setArrayLinks(listDownloadingLink);
        }catch(Exception ex){
            System.out.println(ex.toString());
        }
        return proManager;
    }

    public static ArrayList<String> openDownloadedURL (String path) {
        //lntrung
        ArrayList<String> arrayDownloadedURL = new ArrayList<String>();
        try{
            File file = new File(path);
            if (file.exists() == false){
                System.out.println("Error : " + path + " ko tồn tại.");
                return null;
            }

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(file);

            //Lấy các link đã down
            NodeList nodeList = ((Element)doc.getElementsByTagName("Downloaded").item(0)).getElementsByTagName("Link");
            for(int i = 0; i < nodeList.getLength(); i++){
                Element eleDownloadedLink = (Element)nodeList.item(i);
                arrayDownloadedURL.add(eleDownloadedLink.getAttribute("url"));
            }
        }catch(Exception ex){
            System.out.println(ex.toString());
        }
        return arrayDownloadedURL;
    }

    // Chạy lúc mới khởi tạo 1 ProjectDownloadManager mới.
    public static boolean saveProject(ProjectDownloadManager proManager, String path){
        boolean value = false;
        try {
            DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
            Document doc = docBuilder.newDocument();

            //Create tree
            Element eleProjectDownloadManager = doc.createElement("ProjectDownloadManager");
            doc.appendChild(eleProjectDownloadManager);

            //ProjectAddress
            ProjectAddress proAddress = proManager.getProjectAddress();
            Element eleProjectAddress = doc.createElement("ProjectAddress");
            eleProjectAddress.setAttribute("name", proAddress.getProjectName());
            eleProjectAddress.setAttribute("address", proAddress.getAddress());
            eleProjectAddress.setAttribute("upLink", String.valueOf(proAddress.getUpLink()));
            eleProjectAddress.setAttribute("saveTo", proAddress.getSaveTo());
            eleProjectDownloadManager.appendChild(eleProjectAddress);

            //ListExtension
            Element eleListExtension = doc.createElement("ListExtension");
            ArrayList<String> listExt = proAddress.getListExt();
            for(int i = 0; i < listExt.size(); i++){
                Element eleExt = doc.createElement("Ext");
                eleExt.setAttribute("name", listExt.get(i));
                eleListExtension.appendChild(eleExt);
            }
            eleProjectAddress.appendChild(eleListExtension);

            //ListPattern
            Element eleListPattern = doc.createElement("ListPattern");
            ArrayList<Pattern> listPattern = proAddress.getArrayPattern();
            for(int i = 0; i < listPattern.size(); i++){
                Element elePattern = doc.createElement("Pattern");
                Element eleAllowExt = doc.createElement("AllowExt");
                Element eleDenyExt = doc.createElement("DenyExt");
                Pattern pattern = listPattern.get(i);
                PermissionPattern permissionPattern = pattern.getPermission();
                elePattern.setAttribute("name", pattern.getPattern());
                elePattern.setAttribute("permission", permissionPattern.toString());

                eleAllowExt.setTextContent(pattern.getAllowExt());
                eleDenyExt.setTextContent(pattern.getDenyExt());

                elePattern.appendChild(eleAllowExt);
                elePattern.appendChild(eleDenyExt);
                eleListPattern.appendChild(elePattern);
            }
            eleProjectAddress.appendChild(eleListPattern);

            // ProjectDownloadLinks
            Element eleProjectDownloadLinks = doc.createElement("ProjectDownloadLinks");
            Element eleDownloading = doc.createElement("Downloading");
            Element eleDownloaded = doc.createElement("Downloaded");
            Element eleLink = doc.createElement("Link");
            eleLink.setAttribute("level", String.valueOf(proManager.getStartingAddress().getLevel()));
            eleLink.setAttribute("url", proManager.getStartingAddress().getUrl());
            eleLink.setAttribute("saveTo", proManager.getStartingAddress().getSaveTo());

            eleDownloading.appendChild(eleLink);
            eleProjectDownloadLinks.appendChild(eleDownloading);
            eleProjectDownloadLinks.appendChild(eleDownloaded);
            eleProjectDownloadManager.appendChild(eleProjectDownloadLinks);


            // Save file
            TransformerFactory transfac = TransformerFactory.newInstance();
            Transformer trans = transfac.newTransformer();
            trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            trans.setOutputProperty(OutputKeys.INDENT, "yes");

            StringWriter sw = new StringWriter();
            StreamResult result = new StreamResult(sw);
            DOMSource source = new DOMSource(doc);
            trans.transform(source, result);

            String xmlString = sw.toString();
            xmlString = defaultStringXml + xmlString;

            //print xml
            //System.out.println("Here's the xml:\n\n" + xmlString);

            PrintWriter pw = new PrintWriter(path);
            pw.write(xmlString);
            pw.close();

            value = true;
        }catch(Exception ex){
            System.err.println (ex);
        }
        return value;
    }

    public static boolean moveAndAppendLinks(ArrayList<ProjectDownloadLinks> arrayLink,
                                             String filePath) {
        boolean value = false;
        try{
            File file = new File(filePath);
            if (file.exists() == false){
                System.out.println("Error : " + filePath + " ko tồn tại.");
                return value;
            }

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(file);

            Element eleDownloading = (Element)doc.getElementsByTagName("Downloading").item(0);
            Element eleDownloaded = (Element)doc.getElementsByTagName("Downloaded").item(0);

            Node eleFirstLink = eleDownloading.getElementsByTagName("Link").item(0);
            eleFirstLink = eleDownloading.removeChild(eleFirstLink);
            eleDownloaded.appendChild(eleFirstLink);

            for(int i = 0; i < arrayLink.size(); i++){
                Element eleLink = doc.createElement("Link");
                eleLink.setAttribute("level", String.valueOf(arrayLink.get(i).getLevel()));
                eleLink.setAttribute("url", arrayLink.get(i).getUrl());
                eleLink.setAttribute("saveTo", arrayLink.get(i).getSaveTo());
                eleDownloading.appendChild(eleLink);
            }

            TransformerFactory transfac = TransformerFactory.newInstance();
            Transformer trans = transfac.newTransformer();
            trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            trans.setOutputProperty(OutputKeys.INDENT, "yes");

            StringWriter sw = new StringWriter();
            StreamResult result = new StreamResult(sw);
            DOMSource source = new DOMSource(doc);
            trans.transform(source, result);

            String xmlString = sw.toString();
            xmlString = defaultStringXml + xmlString;

            PrintWriter pw = new PrintWriter(filePath);
            pw.write(xmlString);
            pw.close();

            value = true;
        }catch(Exception ex){
            System.out.println(ex.toString());
        }
        return value;
    }
}